package com.springboot.framework.service.impl;

import com.springboot.framework.dao.entity.Product;
import com.springboot.framework.dao.mapper.ProductMapper;
import com.springboot.framework.enums.Errors;
import com.springboot.framework.enums.StatusEnum;
import com.springboot.framework.exception.BusinessException;
import com.springboot.framework.model.CategoryModel;
import com.springboot.framework.model.ProductModel;
import com.springboot.framework.service.CategoryService;
import com.springboot.framework.service.ProductService;
import com.springboot.framework.service.ShopService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author SWF
 * @Date 2019/6/6 13:40
 **/
@Service
public class ProductServiceImpl implements ProductService {

    @Resource
    private ProductMapper productMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private ShopService shopService;

    @Override
    public ProductModel get(Integer productId) {
        Example example = new Example(Product.class);
        example.and().andEqualTo("id" , productId)
                .andNotEqualTo("status" , StatusEnum.DELETE.getCode());
        Product product = productMapper.selectOneByExample(example);
        return convertProductModelFromProduct(product);
    }

    /**
     * 查询所有商品
     * @param shopId
     * @return
     */
    @Override
    public List<ProductModel> listAll(Integer shopId) {
        Example example = new Example(Product.class);
        example.and().andEqualTo("shopId", shopId)
                .andNotEqualTo("status", StatusEnum.DELETE.getCode());
        example.orderBy("createDate").desc();
        List<Product> products = productMapper.selectByExample(example);

        return convertProductModelFromProduct(products);
    }

    /**
     * 查询所有上架的商品
     *
     * @param shopId
     * @return
     */
    @Override
    public List<ProductModel> listUp(Integer shopId) {
        Example example = new Example(Product.class);
        example.and().andEqualTo("shopId", shopId)
                .andEqualTo("status", StatusEnum.UP.getCode());
        example.orderBy("createDate").desc();
        List<Product> products = productMapper.selectByExample(example);
        return convertProductModelFromProduct(products);
    }

    /**
     * 新增商品
     * @param productModel
     * @return
     */
    @Override
    public ProductModel insert(ProductModel productModel) {
        if(shopService.get(productModel.getShopId()) == null){
            throw new BusinessException("该店铺不存在");
        }
        CategoryModel categoryModel = categoryService.get(productModel.getCategoryId());
        if(categoryModel == null){
            throw new BusinessException("该品类不存在");
        }
        productModel.setCover(categoryModel.getCover());
        Product product = convertProductFromProductModel(productModel);
        int resultCount = productMapper.insertSelective(product);
        if(resultCount == 0){
            throw new BusinessException(Errors.SYSTEM_INSERT_FAIL);
        }
        // 查询商品，并返回
        return this.get(product.getId());
    }

    @Override
    public ProductModel updateStatus(Integer productId, Byte status, Integer shopId) {
        ProductModel productModel = get(productId);
        if(productModel == null){
            throw new BusinessException(Errors.PRODUCT_NOT_EXIST);
        }
        if(!productModel.getShopId().equals(shopId)){
            throw new BusinessException(Errors.SYSTEM_NO_ACCESS);
        }
        Product product = new Product();
        product.setId(productModel.getId());
        product.setStatus(status);
        int resultCount = productMapper.updateByPrimaryKeySelective(product);
        if(resultCount == 0){
            throw new BusinessException(Errors.SYSTEM_UPDATE_ERROR);
        }
        return productModel;
    }

    @Override
    public ProductModel update(ProductModel productModel){
        Product product = convertProductFromProductModel(productModel);
        int resultCount = productMapper.updateByPrimaryKeySelective(product);
        if(resultCount == 0){
            throw new BusinessException(Errors.SYSTEM_UPDATE_ERROR);
        }
        return productModel;
    }

    @Override
    public void increaseStock(Integer productId, Integer quantity){
        productMapper.increaseStock(productId,quantity);
    };

    /**
     * 减库存
     * @param productId
     * @param quantity
     */
    @Override
    public void decreaseStock(Integer productId, Integer quantity) {
        try {
            productMapper.decreaseStock(productId,quantity);
        }catch (Exception e){
            throw new BusinessException("商品库存不足");
        }
    }

    @Override
    public void delete(Integer productId, Integer shopId) {
        updateStatus(productId,StatusEnum.DELETE.getCode(),shopId);
    }


    private ProductModel convertProductModelFromProduct(Product product){
        if(product == null ){
            return null;
        }
        ProductModel productModel = new ProductModel();
        BeanUtils.copyProperties(product,productModel);
        if(null != product.getCategoryId()){
            CategoryModel categoryModel = categoryService.get(product.getCategoryId());
            if(categoryModel!=null){
                productModel.setCategoryName(categoryModel.getName());
            }
        }
        // 查询品类可以优化为单例模式
        return productModel;
    }

    private List<ProductModel> convertProductModelFromProduct(List<Product> products) {
        if (products == null) {
            return null;
        }
        // 获取所有商品类别，并转为map
        List<CategoryModel> categoryModels = categoryService.listAll();
        Map<Integer, String> category = categoryModels.stream().collect(Collectors.toMap(CategoryModel::getId, CategoryModel::getName));

        return products.stream().map(e -> {
            ProductModel productModel = new ProductModel();
            BeanUtils.copyProperties(e, productModel);
            productModel.setCategoryName(category.get(e.getCategoryId()));
            return productModel;
        }).collect(Collectors.toList());
    }

    private Product convertProductFromProductModel(ProductModel productModel){
        if(productModel == null){
            return null;
        }
        Product product = new Product();
        BeanUtils.copyProperties(productModel,product);
        return product;
    }
}
